package com.jiehoo.elove.robot;



import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexUtils {
  private static Pattern regexPattern = Pattern
      .compile("([\\(\\)\\.\\?\\*\\^\\$\\+\\|&&[^\\$\\\\]])");

  private static Pattern trimReturnPattern = Pattern.compile("\\r\\n|\\r|\\n");

  private static Pattern trimTagSpacePattern = Pattern.compile(">\\s+<",
      Pattern.MULTILINE);

  private static String[][] flagPatterns = { { "###", "(\\\\d+)" },
      { "@@@", "([^<]+?)" }, { "%%%", "([^<]+?)" }, { "!!!", "[^<]+?" } };

  public static final String EMPTY = "";

  public static final String TRIMED_TAG = "><";

  private static Map patternMap = new HashMap();

  public static String trimReturnAndTagSpace(String original) {
    return trimTagSpace(trimReturn(original));
  }

  public static String trimReturn(String original) {
    Matcher matcher = trimReturnPattern.matcher(original);
    return matcher.replaceAll(EMPTY);
  }

  public static String trimTagSpace(String original) {
    Matcher matcher = trimTagSpacePattern.matcher(original);
    return matcher.replaceAll(TRIMED_TAG);
  }

  public static String escapeRegex(String original) {
    Matcher matcher = regexPattern.matcher(escapeDollarBackslash(original));
    StringBuffer buffer = new StringBuffer();
    while (matcher.find()) {
      String group = matcher.group();
      matcher.appendReplacement(buffer, "\\\\" + group);
    }
    matcher.appendTail(buffer);
    return buffer.toString();
  }

  public static String escapeDollarBackslash(String original) {
    StringBuffer buffer = new StringBuffer(original.length());
    for (int i = 0; i < original.length(); i++) {
      char c = original.charAt(i);
      if (c == '\\' || c == '$') {
        buffer.append("\\").append(c);
      } else {
        buffer.append(c);
      }
    }
    return buffer.toString();
  }

  public static String convertPattern(String original) {
    String pattern = escapeRegex(original);
    for (int i = 0; i < flagPatterns.length; i++) {
      pattern = pattern.replaceAll(flagPatterns[i][0], flagPatterns[i][1]);
    }
    return pattern;
  }

  public static String[][] parseFlag(String patternString, String string) {
    Pattern pattern = (Pattern) patternMap.get(patternString);
    if (pattern == null) {
      pattern = Pattern.compile(convertPattern(patternString),
          Pattern.MULTILINE);
      patternMap.put(patternString, pattern);
    }
    List list = new ArrayList();
    Matcher matcher = pattern.matcher(string);
    int count = 0;

    int start = 0;
    while (matcher.find(start)) {
      count = matcher.groupCount();
      String match = matcher.group(0);
      String[] matches = new String[count];
      for (int i = 0; i < count; i++) {
        matches[i] = matcher.group(i + 1);
      }
      list.add(matches);
      start = string.indexOf(match, start) + match.length();
    }
    if (list.size() == 0) {
      return new String[0][0];
    } else {
      String[][] result = new String[list.size()][count];
      for (int i = 0; i < list.size(); i++) {
        result[i] = (String[]) list.get(i);
      }
      return result;
    }

  }

}